//
// Copyright (C) 2004-2010  Autodesk, Inc.
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of version 2.1 of the GNU Lesser
// General Public License as published by the Free Software Foundation.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef FDOCMSDELEGATE_H
#define FDOCMSDELEGATE_H

#ifdef _WIN32
#pragma once
#endif // _WIN32

#include <OWS/FdoOwsDelegate.h>
#include "FdoCMSBoundingBox.h"
//#include "math.h"
#include <gdal_priv.h>

class FdoCMSDelegate : public FdoOwsDelegate
{
    friend class FdoCMSDelegateFactory;

protected:
    FdoCMSDelegate():FdoOwsDelegate(NULL, NULL, NULL)
    {
        _InitZoomLevel();
    };

    FdoCMSDelegate(FdoString* serviceUrl, FdoString* apiKey) :
    FdoOwsDelegate(serviceUrl, NULL, NULL),
        m_serviceUrl(serviceUrl),
        m_apiKey(apiKey)
    {
        _InitZoomLevel();
    };

    virtual ~FdoCMSDelegate(){};
    virtual void Dispose(){ delete this; };

    virtual void _InitZoomLevel()
    {
        ////This value comes from OpenLayers
        //FdoDouble zoomLevels[20] = {1.40625, 
        //                            0.703125, 
        //                            0.3515625, 
        //                            0.17578125, 
        //                            0.087890625, 
        //                            0.0439453125,
        //                            0.02197265625, 
        //                            0.010986328125, 
        //                            0.0054931640625, 
        //                            0.00274658203125,
        //                            0.001373291015625, 
        //                            0.0006866455078125, 
        //                            0.00034332275390625,
        //                            0.000171661376953125, 
        //                            0.0000858306884765625, 
        //                            0.00004291534423828125,
        //                            0.00002145767211914062, 
        //                            0.00001072883605957031,
        //                            0.00000536441802978515, 
        //                            0.00000268220901489257}; 
        m_zoomLevels[0] = 512.0 / 360.0;
        for(int i=1;i<20;i++)
        {
            m_zoomLevels[i] = m_zoomLevels[i-1] / 2.0;
        }
    };

    virtual FdoInt32 _CalculateZoomLevel(const FdoCMSBoundingBox* bbox
        , FdoSize expectedImageHeight
        , FdoSize expectedImageWidth
        , FdoInt32 maxZoomLevel
        , FdoSize& imageHeightOut
        , FdoSize& imageWidthOut);

    virtual FdoSize MaxImageSize();
    virtual FdoSize MinImageSize();
protected:
    FdoStringP m_serviceUrl;
    FdoStringP m_apiKey;
    FdoDouble m_zoomLevels[20];
public:

    virtual GDALDataset* GetMapGdalDataset(FdoCMSBoundingBox* bbox,
        FdoSize height,
        FdoSize width,
        FdoString* mapType,
        FdoDouble& retScale) {return NULL;}

    virtual FdoBoolean TestConnection() {return true;}
    virtual bool SplitImageNeeded(FdoCMSBoundingBox* bbox
        , FdoSize expectedImageHeight
        , FdoSize expectedImageWidth
        , FdoInt32 maxZoomLevel
        , FdoSize& imageHeightOut
        , FdoSize& imageWidthOut
        , FdoInt32& zoomLevelOut);

    virtual FdoCMSImageSpaceTileManager*
        FdoCMSDelegate::SplitImage(FdoCMSBoundingBox* bbox
        , FdoInt32 zoomLevel
        , FdoSize heightMatched
        , FdoSize widthMatched);
    virtual void VerifyImageSize(FdoSize& imageHeightOut, FdoSize& imageWidthOut);
};

typedef FdoPtr<FdoCMSDelegate> FdoCMSDelegateP;

#endif


